/*
Copyright 2010 Christian Dadswell
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package subscriber.chrisdadswell.co.uk;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.util.Log;

public class Func_JSOUP {
	private static final String _APP_TAG = "Func_JSOUP";
	private static final String _AUTHPARAMS = "GoogleLogin auth=";
	private static final String _GOOGLE_LOGIN_URL = "https://www.google.com/accounts/ClientLogin";
	private static final String _READER_BASE_URL	= "http://www.google.com/reader/";
	private static final String _API_URL = _READER_BASE_URL + "api/0/";
	private static final String _TOKEN_URL = _API_URL + "token";
	private static final String _USER_INFO_URL = _API_URL + "user-info";
	private static final String _USER_LABEL = "user/-/label/";
	private static final String _TAG_LIST_URL = _API_URL + "tag/list";
	private static final String _EDIT_TAG_URL = _API_URL + "tag/edit";
	private static final String _RENAME_TAG_URL = _API_URL + "rename-tag";
	private static final String _DISABLE_TAG_URL = _API_URL + "disable-tag";
	private static final String _SUBSCRIPTION_URL = _API_URL + "subscription/edit";
	private static final String _SUBSCRIPTION_LIST_URL = _API_URL + "subscription/list";
	
	
	/**
	 * Returns a Google Authentication Key 
	 * <p>
	 * Requires a Google Username and Password to be sent in the POST headers 
	 * to http://www.google.com/accounts/ClientLogin
	 * 
	 * @param  GoogleGoogle_Username Google Username
	 * @param  Google_Password Google Password
	 * @return      Google authorisation token
	 * @see         GetToken
	 */
	public static String getGoogleAuthKey(String _USERNAME, String _PASSWORD) throws UnsupportedEncodingException, IOException {
	    Document doc = Jsoup.connect(_GOOGLE_LOGIN_URL)
		.data("accountType", "GOOGLE",
				"Email", _USERNAME,
				"Passwd", _PASSWORD,
				"service", "reader",
				"source", "Subscriber")
		.userAgent("subscriber.chrisdadswell.co.uk")
		.timeout(4000)
		.post();

	    // RETRIEVES THE RESPONSE TEXT inc SID and AUTH
	    String _AUTHKEY = doc.body().text().substring(doc.body().text().indexOf("Auth="), doc.body().text().length());
	    _AUTHKEY = _AUTHKEY.replace( "Auth=","" );
	    return _AUTHKEY;
    }

	/**
	 * Returns a Google Token 
	 * <p>
	 * Requires a Google Username and Password to be sent in the GET headers 
	 * to http://www.google.com/reader/api/0/token
	 * 
	 * @param  Google_Username Google Username
	 * @param  Google_Password Google Password
	 * @return      Google authorisation token
	 * @see         GetAuthKey
	 */
	public static String getGoogleToken(String _USERNAME, String _PASSWORD) throws UnsupportedEncodingException, IOException {
	    Document doc = Jsoup.connect(_TOKEN_URL)
	    .header("Authorization", _AUTHPARAMS + getGoogleAuthKey(_USERNAME,_PASSWORD))
		.userAgent("subscriber.chrisdadswell.co.uk")
		.timeout(4000)
		.get();

	    // RETRIEVES THE RESPONSE TOKEN
	    String _TOKEN = doc.body().text();
	    return _TOKEN;
	}
	
	/**
	 * Returns Google Reader User Info 
	 * <p>
	 * Requires a Google Username and Password to be sent in the POST headers 
	 * to http://www.google.com/reader/api/0/user-info
	 * 
	 * @param  GoogleGoogle_Username Google Username
	 * @param  Google_Password Google Password
	 * @return      Google Reader User Info
	 * @see         GetToken
	 */
	public static String getUserInfo(String _USERNAME, String _PASSWORD) throws UnsupportedEncodingException, IOException {
	    Document doc = Jsoup.connect(_USER_INFO_URL)
	    .header("Authorization", _AUTHPARAMS + getGoogleAuthKey(_USERNAME,_PASSWORD))
		.userAgent("subscriber.chrisdadswell.co.uk")
		.timeout(4000)
		.get();
	    
	    // RETRIEVES THE RESPONSE USERINFO
	    String _USERINFO = doc.body().text();
	    return _USERINFO;
	}
	
	/**
	 * Returns Google User ID 
	 * <p>
	 * Requires a Google Username and Password to be sent in the POST headers 
	 * to http://www.google.com/accounts/ClientLogin
	 * 
	 * @return      Google User ID
	 * @see         GetToken, GetAuthKey
	 */
	
	public static String getGoogleUserID(String _USERNAME, String _PASSWORD) throws UnsupportedEncodingException, IOException {
			/* USERINFO
			 * {"userId":"14577161871823252783",
			 * "userName":"Chris","userProfileId":"111618249557856839702",
			 * "userEmail":"chrisdadswell@gmail.com",
			 * "isBloggerUser":true,
			 * "signupTimeSec":1159535065}
			 */
			String _USERINFO = getUserInfo(_USERNAME, _PASSWORD);
			String _USERID = (String) _USERINFO.subSequence(11, 31);
			return _USERID;
	}
	
	/**
	 * Returns a hashmap of Google Reader Tags and Tag id's 
	 * <p>
	 * Requires a Google Username and Password to be sent in the POST headers 
	 * to http://www.google.com/accounts/ClientLogin
	 * 
	 * @param  Google_Username Google Username
	 * @param  Google_Password Google Password
	 * @return      Google Reader Tags and Tag ID's
	 * @see         
	 */
	public static String[] getTagList(String _USERNAME, String _PASSWORD) {
		Log.d(_APP_TAG, "METHOD: getTagList()");
		ArrayList<String> _TAGTITLE_ARRAYLIST = new ArrayList<String>();
		String _TAG_LABEL = null;
		try {
			_TAG_LABEL = "user/" + getGoogleUserID(_USERNAME,_PASSWORD) + "/label/";
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Document doc = null;
		try {
			doc = Jsoup.connect(_TAG_LIST_URL)
			.header("Authorization", _AUTHPARAMS + getGoogleAuthKey(_USERNAME,_PASSWORD))
			.userAgent("subscriber.chrisdadswell.co.uk")
			.timeout(6000)
			.get();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    
	    Elements links = doc.select("string");
	    for (Element link : links) {
		    String tagAttrib = link.attr("name");
		    String tagText = link.text();
		    if(Func_Strings.FindWordInString(tagText, _TAG_LABEL)) {
			    _TAGTITLE_ARRAYLIST.add(tagText.substring(32));
		    }
	    }

    	String[] _TAGTITLE_ARRAY = new String[_TAGTITLE_ARRAYLIST.size()]; 
	    _TAGTITLE_ARRAYLIST.toArray(_TAGTITLE_ARRAY);
		return _TAGTITLE_ARRAY;
	}
		
	public static boolean tagsInReader(String _USERNAME, String _PASSWORD) {
		Log.d(_APP_TAG, "METHOD: tagsInReader(" + _USERNAME + "," + _PASSWORD + ")");
		String[] _TAG_LIST = getTagList(_USERNAME, _PASSWORD);
		Log.d(_APP_TAG, "VAR: Tag list size = " + _TAG_LIST.length);
		
		if(_TAG_LIST.length > 0){
			return true;
		}else{
			return false;
		}
	}
	
	public static String[] getSubList(String _USERNAME, String _PASSWORD) throws UnsupportedEncodingException, IOException {
		ArrayList<String> _SUBTITLE_ARRAYLIST = new ArrayList<String>();
		
		Document doc = Jsoup.connect(_SUBSCRIPTION_LIST_URL)
	    .header("Authorization", _AUTHPARAMS + getGoogleAuthKey(_USERNAME,_PASSWORD))
		.userAgent("subscriber.chrisdadswell.co.uk")
		.timeout(5000)
		.get();
	    
	    Elements links = doc.select("string");
	    
	    for (Element link : links) {
		    String tagAttrib = link.attr("name");
		    String tagText = link.text();
			    _SUBTITLE_ARRAYLIST.add(tagText);
	    }

    	String[] _SUBTITLE_ARRAY = new String[_SUBTITLE_ARRAYLIST.size()]; 
	    _SUBTITLE_ARRAYLIST.toArray(_SUBTITLE_ARRAY);
		return _SUBTITLE_ARRAY;
		
	}
	
	public static boolean Subscription(String _SUBTYPE, String _FEEDURL, String _SUBTITLE, 
			String _SUBTAG, String _USERNAME, String _PASSWORD) throws IOException {
		
		Log.d(_APP_TAG, "METHOD: Subscription(" + _SUBTYPE + "," + _FEEDURL + "," + _SUBTITLE + "," + 
				_SUBTAG + "," + "USERNAME,PASSWORD)");
		String _TOKEN = getGoogleToken(_USERNAME, _PASSWORD);
		String _AUTHKEY = getGoogleAuthKey(_USERNAME,_PASSWORD);
		/*
		 *  PARAMS
		 *  s = feed/ <feedURL>
		 *  t = title
		 *  a = add label - s=http://xkcd.com/rss.xml&ac=edit&a=user/-/label/comics&token=<token>
		 *  R = ??
		 *  ac = subscribe | unsubscribe
		 *  T = Token
		 *  source = where are we coming from
		 */
		Document doc = Jsoup.connect(_SUBSCRIPTION_URL)
	    .header("Authorization", _AUTHPARAMS + _AUTHKEY)
		.data("s", "feed/" + _FEEDURL,
				"ac", _SUBTYPE,
				"a", _USER_LABEL + _SUBTAG,
				"t", _SUBTITLE,
				"T", _TOKEN,
				"R", "/reader/m/directory?newSub=true&newStreamSub=feed"  + URLEncoder.encode("/") + URLEncoder.encode(_FEEDURL), "UTF-8")
		.userAgent("subscriber.chrisdadswell.co.uk")
		.timeout(4000)
		.post();

	    // RETRIEVES THE RESPONSE
	    String _RESPONSE = doc.body().text();
	    Log.d(_APP_TAG, "RESPONSE: " + _RESPONSE);
	    if(_RESPONSE == "OK") {
	    	return true;
	    }else{
		    return false;
	    }
	}

	public static boolean tagShare(String _USERNAME, String _PASSWORD, String _USERID, String _TAG_TITLE, String _SHARE_TYPE) throws UnsupportedEncodingException, IOException {
		Log.d(_APP_TAG, "METHOD: tagShare()");
		/*
		 *MAKE TAG PUBLIC
		 *POST TO 
		 *http://www.google.com/reader/api/0/tag/edit?
		 *PARAMS
		 *s=user%2F14577161871823252783%2Flabel%2FVMWare&t=VMWare&pub=true&T=LuQOPECnfFbY_CagmRwmgg<token> 
		 */
		
		String _STR_PATTERN = "OK";
	    Pattern pattern = Pattern.compile(_STR_PATTERN);
	    Matcher matcher = pattern.matcher("");
		
		String _AUTHKEY = getGoogleAuthKey(_USERNAME,_PASSWORD);
		String _TOKEN = getGoogleToken(_USERNAME, _PASSWORD);
		
		String _TAG_TYPE = "edit";
		String _TAG_URL = null;
		if(_SHARE_TYPE == "Public") {
			_SHARE_TYPE = "true";
		}else if(_SHARE_TYPE == "Private"){
			_SHARE_TYPE = "false";
		}

	    if(_TAG_TYPE == "edit") {
	    	_TAG_URL = _EDIT_TAG_URL;
	    }else if(_TAG_TYPE == "disable") {
	    	_TAG_URL = _DISABLE_TAG_URL;
	    }else if(_TAG_TYPE == "rename"){
	    	_TAG_URL = _RENAME_TAG_URL;
	    }

		Document doc = Jsoup.connect(_TAG_URL)
	    .header("Authorization", _AUTHPARAMS + _AUTHKEY)
		.data("s", "user" + "/"+ _USERID + "/label/" + _TAG_TITLE,
				"pub", _SHARE_TYPE,
				"T", _TOKEN)
		.userAgent("subscriber.chrisdadswell.co.uk")
		.timeout(4000)
		.post();

	    // RETRIEVES THE RESPONSE
	    String _RESPONSE = doc.body().text();
	    Log.d(_APP_TAG, "RESPONSE: " + _RESPONSE);
	    
	    matcher.reset(_RESPONSE);
        if (matcher.find()) {
    		Log.d(_APP_TAG, "RESPONSE: successful! (" + _RESPONSE + ")");
    		return true;
        }else{
    		Log.d(_APP_TAG, "RESPONSE: unsuccessful (" + _RESPONSE + ")");
    		return false;
        	
        }

	}
	
	
	public static HashMap getAvailableFeeds(String SiteURL) throws IOException {
		HashMap <String, String> _FEED_HASHMAP = new HashMap();
	
		String _HEADCONTENT = Func_HTTP.GetHeadContent(SiteURL) + "<body>\n" + "</body>\n" + "</html>";
		Document doc = Jsoup.parse(_HEADCONTENT, SiteURL);
		Elements links = doc.select("[type=application/rss+xml]");
		for (Element link : links) {
			_FEED_HASHMAP.put(link.attr("title"), link.attr("abs:href"));
		}
		return _FEED_HASHMAP;
	}
	
	
	public static HashMap getAvailableFeedsURL(String _SITE_URL) throws IOException {
		Log.d(_APP_TAG, "METHOD: getAvailableFeeds()");
		HashMap <String, String> _FEED_HASHMAP = new HashMap();
		Document doc = Jsoup.connect(_SITE_URL)
		.timeout(6000)
		.get();
		
		
		Log.d(_APP_TAG, "VARS: Doc content = " + doc.body());
		
		Elements links = doc.select("[type=application/rss+xml]");
		Log.d(_APP_TAG, "VARS: Links found = " + links.size());
		for (Element link : links) {
			_FEED_HASHMAP.put(link.attr("title"), link.attr("abs:href"));
		}
		return _FEED_HASHMAP;
	}
}